Add the BitConverter Half members - #600
Merged
Merged
Conversation
Eight members: GetBytes, HalfToInt16Bits, HalfToUInt16Bits, Int16BitsToHalf, UInt16BitsToHalf, ToHalf over an array and over a span, and TryWriteBytes. The window is net5.0 alone. Half arrived in net5.0 but every one of these BitConverter members is net6.0, so below net5.0 there is no type to convert and from net6.0 the BCL has them. Noted on each, since the section header does not show it. Reinterpretation goes through MemoryMarshal over a two byte stack buffer rather than through float, which would lose NaN payloads. Verified exhaustively: all 65536 bit patterns round trip and agree with the BCL byte for byte, including every NaN payload, both infinities, negative zero and the subnormal boundary. The polyfill only compiles on net5.0, whose runtime is not installed here, so the net5.0 test build was run on the net11 runtime with roll forward to exercise it. That build compiling at all already requires the polyfill, since net5.0 has none of these members, and all 1655 tests pass there. API count 1139 -> 1147.
This was referenced Sep 10, 2026
This was referenced Sep 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Eight members:
GetBytes(Half),HalfToInt16Bits,HalfToUInt16Bits,Int16BitsToHalf,UInt16BitsToHalf,ToHalfover an array and over a span, andTryWriteBytes(Span<byte>, Half).The window really is net5.0 alone
I flagged this as poor value in #598 and should be precise about why, because it is narrower than it looks:
Halfthe type is net5.0.So below net5.0 there is nothing to convert, and from net6.0 the BCL supplies them. One target framework. Each member carries a
//Note:saying so, the same way theInt128members do, since the#### BitConvertersection header gives no hint of a floor.Narrow, but the value is real for anyone still on net5.0: today they have no way to get at a
Half's bits at all, because the type deliberately exposes none.Reinterpretation, not conversion
The obvious shortcut — round through
float— silently destroys NaN payloads and would produce a canonical NaN for every one of the 2046 distinct NaN encodings. So the bits go throughMemoryMarshalover a two-byte stack buffer, which is exact and allocation-free (GetBytesallocates its 2-byte array, as the BCL does). No unsafe code and no dependency onUnsafe.Endianness cancels out for the
*Bits*members: writing aHalfin platform order and reading ashortback in platform order yields the same sixteen bits either way.Verified exhaustively
Halfis 16 bits, so this does not need sampling. All 65 536 patterns were swept against the BCL before the code was written, and the shipped tests do the same sweep: every pattern round trips, andGetBytes,ToHalfandTryWriteBytesagree with the BCL byte for byte. Zero mismatches, including every NaN payload, both infinities, negative zero, and the subnormal boundary. Nine notable patterns are also pinned explicitly, so a regression names the case rather than just a count.Argument validation matches the array overloads already on the type —
ArgumentNullExceptionon null,ArgumentOutOfRangeExceptiononstartIndexoutside the array, andArgumentExceptionnamingvaluewhen the index is in range but only one byte remains.How the polyfill was actually exercised
This is the awkward part, and worth stating plainly: the polyfill compiles only on net5.0, and that runtime is not installed on this machine, so a normal test run would have exercised the BCL and never the polyfill.
So the net5.0 test build was run against the net11 runtime with
dotnet exec --roll-forward LatestMajor. That build compiling at all already proves the polyfill is doing the work — net5.0 has none of these members, so without it there would be nothing to bind to — and all 1655 tests pass there, including the exhaustive sweep. CI, which has the net5.0 runtime, will run it natively.Result
API count 1139 → 1147.
Solution clean in Release, Consume clean across all 22 TFMs, tests green on net11.0 (1714), net10.0 (1714), net9.0 (1714), net8.0 (1711), net462 (1665), net5.0 via roll-forward (1655), plus PublicTests, EmbeddedTests, UnsafeTests, NoRefsTests and NoExtrasTests.